// 
//  Copyright (C) 2009 Jacek Trubłajewicz
// 
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//  
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// 

using System;
using System.Drawing;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Xml.Serialization;
using Mono.Unix;


namespace wxGadu
{
	[Serializable]
	public class ProfileData
	{
		private string profileName;
		private string passwordHash;
		private string salt;
		
		public string ProfileName
		{
			get { return profileName; }
			set { profileName = value; }
		}
		
		public string PasswordHash
		{
			get { return passwordHash; }
			set { passwordHash = value; }
		}
		
		public string Salt
		{
			get { return salt; }
			set { salt = value; }
		}
	}
	
	/// <summary>
	/// Represents dialog used for selecting user profile 
	/// upon application startup
	/// </summary>
	public class LoginDialog : wx.Dialog
	{
		#region Id
		private enum Id
		{
			mainProfileNameCombo,
			mainPasswordTC,
			moreButton,
			addProfileButton,
			removeProfileButton,
			upButton,
			downButton,
			profilesList,
			profileNameTC,
			passwordTC,
			changePasswordButton
		}
		#endregion
		
		#region sizers
		private wx.BoxSizer boxSizer;
		private wx.BoxSizer topSizer;
		private wx.BoxSizer buttonSizer;	
		private wx.StaticBoxSizer profileSizer;
		private wx.BoxSizer moreSizer;
		#endregion
		
		#region controls
		private wx.ComboBox mainProfileNameCombo;
		private wx.TextCtrl mainPasswordTC;
		private wx.Button okButton;
		private wx.Button cancelButton;
		private wx.Button moreButton;
		private wx.Button addProfileButton;
		private wx.Button removeProfileButton;
		private wx.Button upButton;
		private wx.Button downButton;
		private wx.Button changePasswordButton;
		private wx.ListBox profilesList;
		private wx.TextCtrl profileNameTC;
		private wx.TextCtrl passwordTC;
		private wx.StaticBitmap passwordBitmap;
		#endregion
		
		#region data members
		private string profilesFile;
		private List<ProfileData> profiles;
		private string profileName;
		private string password;
		private string homeDir;
		private ImageManager imageManger;
		#endregion
		
		public LoginDialog(wx.Window parent, int id, string title, Point pos, Size size, uint style, ImageManager imgr):
			base(parent, id, title, pos, size, style)
		{
			imageManger = imgr;
			
			DoControls();
			DoControlsProperties();
			DoLayout();
			
			StringBuilder sb = new StringBuilder();
			sb.Append(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
			sb.Append(Path.DirectorySeparatorChar); 
			sb.Append(".");
			sb.Append(AppConfig.APP_NAME);
			homeDir = sb.ToString();
			sb.Append(Path.DirectorySeparatorChar); 
			sb.Append(AppConfig.PROFILES_FILE_NAME);
			profilesFile = sb.ToString();
			
				
			EVT_BUTTON((int) Id.moreButton, new wx.EventListener(OnMoreButtonClicked));
			EVT_BUTTON((int) Id.addProfileButton, new wx.EventListener(OnAddButtonClicked));
			EVT_BUTTON((int) Id.removeProfileButton, new wx.EventListener(OnRemoveButtonClicked));
			EVT_BUTTON((int) Id.upButton, new wx.EventListener(OnUpButtonClicked));
			EVT_BUTTON((int) Id.downButton, new wx.EventListener(OnDownButtonClicked));
			EVT_BUTTON((int) Id.changePasswordButton, new wx.EventListener(OnChangePasswordButtonClicked));
		}
		
		protected void DoControls()
		{
			mainProfileNameCombo = new wx.ComboBox(this, (int) Id.mainProfileNameCombo, string.Empty,
			                                       wx.Window.wxDefaultPosition, wx.Window.wxDefaultSize,
			                                       new string[0], wx.ComboBox.wxCB_READONLY);
			mainPasswordTC = new wx.TextCtrl(this, (int) Id.mainPasswordTC, string.Empty, 
			                                 wx.Window.wxDefaultPosition, wx.Window.wxDefaultSize,
			                                 wx.TextCtrl.wxTE_PASSWORD);
			okButton = new wx.Button(this, wx.Window.wxID_OK, string.Empty);
			cancelButton = new wx.Button(this, wx.Window.wxID_CANCEL, string.Empty);
			moreButton = new wx.Button(this, (int) Id.moreButton, ">>", 
			                           wx.Window.wxDefaultPosition, wx.Window.wxDefaultSize,
			                           wx.Button.wxBU_EXACTFIT);
			addProfileButton = new wx.Button(this, (int) Id.addProfileButton, Catalog.GetString("Add"));
			removeProfileButton = new wx.Button(this, (int) Id.removeProfileButton, Catalog.GetString("Remove"));
			upButton = new wx.Button(this, (int) Id.upButton, Catalog.GetString("Up"));
			downButton = new wx.Button(this, (int) Id.downButton, Catalog.GetString("Down"));
			changePasswordButton = new wx.Button(this, (int) Id.changePasswordButton, Catalog.GetString("Change password"));
			profilesList = new wx.ListBox(this, (int) Id.profilesList, wx.Window.wxDefaultPosition, new Size(80, 100));
			profileNameTC = new wx.TextCtrl(this, (int) Id.profileNameTC, string.Empty);
			passwordTC = new wx.TextCtrl(this, (int) Id.passwordTC, string.Empty, 
			                             wx.Window.wxDefaultPosition, wx.Window.wxDefaultSize, 
			                             wx.TextCtrl.wxTE_PASSWORD);
			passwordBitmap = new wx.StaticBitmap(this, imageManger[ImageManager.LOGIN_PASSWORD]);
		}
		
		protected void DoControlsProperties()
		{
			okButton.SetDefault();
			mainPasswordTC.SetFocus();
			okButton.ToolTip = Catalog.GetString("Press to login");
			mainProfileNameCombo.ToolTip = Catalog.GetString("Select profile into which you want to log");
			mainPasswordTC.ToolTip = Catalog.GetString("Input profile password");
			moreButton.ToolTip = Catalog.GetString("Show/hide profile manager");
			cancelButton.ToolTip = Catalog.GetString("Close application");
			addProfileButton.ToolTip = Catalog.GetString("Adds new profile to the list");
			removeProfileButton.ToolTip = Catalog.GetString("Deletes selected profile from the list");
			passwordTC.ToolTip = Catalog.GetString("Input profile password, this password _should_ be the same as your GG account password");
			profileNameTC.ToolTip = Catalog.GetString("Input your profile name");
			upButton.ToolTip = Catalog.GetString("Move selected profile up on the list");
			downButton.ToolTip = Catalog.GetString("Move selected profile down on the list");
			changePasswordButton.ToolTip = Catalog.GetString("Change selected profile password, use this feature when you change GG account password");
		}
		
		protected void DoLayout()
		{
			topSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
			{
				boxSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
				{
					wx.BoxSizer imageSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
					{
						wx.StaticBox profileInput = new wx.StaticBox(this, Catalog.GetString("Select profile"));
						profileSizer = new wx.StaticBoxSizer(profileInput, wx.Orientation.wxVERTICAL);
						{
							profileSizer.Add(mainProfileNameCombo, 0, wx.Stretch.wxEXPAND|wx.Direction.wxTOP|wx.Direction.wxBOTTOM, 5);
							profileSizer.Add(mainPasswordTC, 0, wx.Stretch.wxEXPAND);
						}
						imageSizer.Add(profileSizer, 1, 0, 0);
						
						imageSizer.Add(passwordBitmap, 0, wx.Alignment.wxALIGN_CENTER_VERTICAL|wx.Direction.wxLEFT|wx.Direction.wxTOP, 10);
					}
					boxSizer.Add(imageSizer, 0, wx.Stretch.wxEXPAND);
					//boxSizer.Show(profileSizer, false);
					
					buttonSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
					{
						buttonSizer.Add(20, 20, 1, 0, 0);
						buttonSizer.Add(okButton, 0, 0);
						buttonSizer.Add(10, 20, 0, 0, 0);
						buttonSizer.Add(cancelButton, 0, 0);
						buttonSizer.Add(10, 20, 0, 0, 0);
						buttonSizer.Add(moreButton, 0, 0);
						buttonSizer.Add(20, 20, 1, 0, 0);
					}
					boxSizer.Add(buttonSizer, 0, wx.Stretch.wxEXPAND|wx.Direction.wxBOTTOM|wx.Direction.wxTOP, 10);
					
					// sizer for advenced options
					moreSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
					{
						wx.StaticBox staticBox = new wx.StaticBox(this, -1, Catalog.GetString("Add/remove profile"));
						wx.StaticBoxSizer staticBoxSizer = new wx.StaticBoxSizer(staticBox, wx.Orientation.wxHORIZONTAL);
						{
							wx.BoxSizer leftSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
							{
								wx.BoxSizer inputSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
								{
									inputSizer.Add(new wx.StaticText(this, Catalog.GetString("Profile name: ")), 
								               0, 0);
									inputSizer.Add(profileNameTC, 0, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
									inputSizer.Add(new wx.StaticText(this, Catalog.GetString("Gadu-Gadu password: ")), 
								               0, 0);
									inputSizer.Add(passwordTC, 0, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
								}
								leftSizer.Add(inputSizer, 1, wx.Stretch.wxEXPAND);
								
								wx.BoxSizer controlListSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
								{
									controlListSizer.Add(20, 20, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
									controlListSizer.Add(addProfileButton, 0, wx.Direction.wxALL, 5);
									controlListSizer.Add(removeProfileButton, 0, wx.Direction.wxALL, 5);
									controlListSizer.Add(10, 10, 0, 0, 5);
									controlListSizer.Add(changePasswordButton, 0, wx.Direction.wxALL, 5);
									controlListSizer.Add(20, 20, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
								}
								leftSizer.Add(controlListSizer, 0, wx.Stretch.wxEXPAND|wx.Direction.wxALL|
								              wx.Alignment.wxALIGN_RIGHT, 5);
								
							}
							staticBoxSizer.Add(leftSizer, 1, wx.Stretch.wxEXPAND|wx.Direction.wxTOP, 5); 
							
							wx.BoxSizer rightSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
							{
								wx.BoxSizer listSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
								{
									listSizer.Add(new wx.StaticText(this, Catalog.GetString("Profiles: ")),
								               0, wx.Alignment.wxALIGN_CENTER_VERTICAL|
								               wx.Direction.wxALL, 5);
								
									listSizer.Add(profilesList, 1, wx.Stretch.wxEXPAND|
								               wx.Direction.wxALL, 5);

								}
								rightSizer.Add(listSizer, 1, wx.Stretch.wxEXPAND, 0);
								
								wx.BoxSizer upDownSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
								{
									upDownSizer.Add(20, 20, 1, 0, 0);
									upDownSizer.Add(upButton, 0, wx.Direction.wxBOTTOM|wx.Direction.wxLEFT, 5);
									upDownSizer.Add(downButton, 0, wx.Direction.wxLEFT, 5);
									upDownSizer.Add(20, 20, 1, 0, 0);
								}
								rightSizer.Add(upDownSizer, 0, wx.Stretch.wxEXPAND);
								
							}
							staticBoxSizer.Add(rightSizer, 1, wx.Stretch.wxEXPAND|wx.Direction.wxTOP, 5);			
						}
						moreSizer.Add(staticBoxSizer, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
										
					}
					boxSizer.Add(moreSizer, 1, wx.Stretch.wxEXPAND);
					boxSizer.Show(moreSizer, false);
					
				}
				topSizer.Add(boxSizer, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
			}
			topSizer.SetSizeHints(this);
			this.Sizer = topSizer;
		}
		
		protected void OnMoreButtonClicked(object sender, wx.Event evt)
		{
			boxSizer.Show(moreSizer, !(boxSizer.IsShown(moreSizer)));
			if (boxSizer.IsShown(moreSizer))
				moreButton.Label = "<<";
			else
				moreButton.Label = ">>";
			
			topSizer.SetSizeHints(this);
			this.Center();
		}
		
		public override bool TransferDataToWindow()
		{
			// read profiles file and fill controls with data
			FillControls();

			return true;
		}
		
		public override bool TransferDataFromWindow()
		{
			int selection = mainProfileNameCombo.Selection;
			if (selection == -1)
			{
				wx.MessageDialog md = new wx.MessageDialog(this, 
					                                                                Catalog.GetString(@"You have to select existing profile. 
															Please add one or more profiles if you don't have any."),
				                                           Catalog.GetString("Invalid profile"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
				md.ShowModal();     
			}
			else
			{
				SaltedHash.SaltedHash hasher = new SaltedHash.SaltedHash();
				string hash = profiles[selection].PasswordHash;
				string salt = profiles[selection].Salt;
				
				if (hasher.VerifyHashString(mainPasswordTC.Value, hash, salt))
				{
					profileName = profiles[selection].ProfileName;
					password = mainPasswordTC.Value;
					mainPasswordTC.Value = string.Empty;
				}
				else
				{
					wx.MessageDialog md = new wx.MessageDialog(this, 
					                                                                Catalog.GetString(@"Entered password doesn't match with the selected profile."),
				                                           Catalog.GetString("Invalid password"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
					md.ShowModal();     
					mainPasswordTC.SelectAll();
					return false;
				}
			}
			
			return true;
		}
		
		private List<ProfileData> ReadProfileList()
		{
			if (File.Exists(profilesFile))
			{
				XmlSerializer serializer = new XmlSerializer(typeof(ProfileData[]));
				ProfileData[] profilesArray;
				List<ProfileData> profilesL = new List<ProfileData>();
				StreamReader reader = new StreamReader(profilesFile);
				try
				{
					profilesArray = (ProfileData[]) serializer.Deserialize(reader);		
					foreach (ProfileData pd in profilesArray)
					{
						profilesL.Add(pd);
					}
					
					return profilesL;
				}
				catch
				{
					throw;
				}
				finally
				{
					reader.Close();
				}
			}
			else
				return new List<ProfileData>();
		}
		
		private void WriteProfileList(List<ProfileData> list)
		{
//			if (list.Count == 0)
//				return;
			
			if (!Directory.Exists(homeDir))
			{
				try
				{
					Directory.CreateDirectory(homeDir);
				}
				catch (Exception e)
				{
					wx.MessageDialog md3 = new wx.MessageDialog(this, String.Format(
					                                                                Catalog.GetString("Unable to create user home directory {0}. Check your permissions and restart the application. \n\n{1}"),
				                                                               homeDir, e.Message),
				                                           Catalog.GetString("Error"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
					md3.ShowModal();
					Environment.Exit(0);
				}
			}
			
			FileStream writer = new FileStream(profilesFile, FileMode.Create, FileAccess.Write);
			try
			{
				ProfileData[] pd = new ProfileData[list.Count];
				list.CopyTo(pd);
				
				XmlSerializer serializer = new XmlSerializer(typeof(ProfileData[]));
				serializer.Serialize(writer, pd);
			}
			catch
			{
				throw;
			}
			finally
			{
				writer.Close();
			}		
		}
		
		private void FillControls()
		{
			try
			{
				profiles = ReadProfileList();
			}
			catch (System.Xml.XmlException e)
			{
				wx.MessageDialog md = new wx.MessageDialog(this, String.Format(Catalog.GetString("Profiles file is damaged, moving exising file to:\n {0}"),
				                                                               profilesFile + ".error"),
				                                           Catalog.GetString("Invalid profiles file"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
				md.ShowModal();     
				try
				{
					File.Move(profilesFile, profilesFile + ".error");
				}
				catch (Exception ex)
				{
					wx.MessageDialog md2 = new wx.MessageDialog(this, String.Format(
					                                                                Catalog.GetString("Unable to move profiles file, check your permissions and restart application:\n\n{0}"),
				                                                               ex.Message),
				                                           Catalog.GetString("Error"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
					md2.ShowModal();     
				}
				profiles = new List<ProfileData>();
				return;				
			}
			
			mainProfileNameCombo.Clear();
			profilesList.Clear();
			
			if (profiles.Count < 1)
			{
				profiles = new List<ProfileData>();
				return;				
			}
					
			for (int i = 0; i < profiles.Count; i++) 
			{
				mainProfileNameCombo.Insert(profiles[i].ProfileName, i);
				profilesList.Insert(profiles[i].ProfileName, i);
			}

			if (!mainProfileNameCombo.IsEmpty)
				mainProfileNameCombo.Select(0);
			else
				mainProfileNameCombo.SetStringSelection(string.Empty);
		}
		
		private void OnAddButtonClicked(object sender, wx.Event evt)
		{
			if ((profileNameTC.Value.Trim() != string.Empty) && (passwordTC.Value.Trim() != string.Empty))
			{
				foreach (ProfileData pd in profiles)
				{
					if (pd.ProfileName == profileNameTC.Value.Trim())
					{
						wx.MessageDialog md = new wx.MessageDialog(this, Catalog.GetString("Profile name cannot be the same as exisiting profile name"), 
				                                           Catalog.GetString("Incorrect values enterd"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
						md.ShowModal();     
				
						return;
					}
				}
				
				ProfileData newProfile = new ProfileData();
				newProfile.ProfileName = profileNameTC.Value;
				SaltedHash.SaltedHash hasher = new SaltedHash.SaltedHash();
				string hash, salt;
				hasher.GetHashAndSaltString(passwordTC.Value.Trim(), out hash, out salt);
				newProfile.PasswordHash = hash;
				newProfile.Salt = salt;
				profiles.Add(newProfile);
				
				try
				{
					WriteProfileList(profiles);
				}
				catch (Exception e)
				{
					wx.MessageDialog md = new wx.MessageDialog(this, String.Format(
					                                                               Catalog.GetString("Unable to write to profiles file:\n{0}\ncheck your permission\n\n{1}"), 
					                                                               profilesFile, e.Message),
				                                           Catalog.GetString("Error"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
					md.ShowModal();
					profiles.RemoveAt(profiles.Count-1);
					profileNameTC.Value = string.Empty;
					passwordTC.Value = string.Empty;
					
					return;
				}
				
				mainProfileNameCombo.Insert(newProfile.ProfileName, mainProfileNameCombo.Count);
				profilesList.Insert(newProfile.ProfileName, profilesList.Count);
			
				profileNameTC.Value = string.Empty;
				passwordTC.Value = string.Empty;
				mainProfileNameCombo.Select(0);
			}
			else
			{
				wx.MessageDialog md = new wx.MessageDialog(this, Catalog.GetString("Profile name and password cannot be empty"), 
				                                           Catalog.GetString("Incorrect values enterd"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
				md.ShowModal();     
				
				return;
			}
		}
		
		private void OnRemoveButtonClicked(object sender, wx.Event evt)
		{
			if (profilesList.Selection == -1)
				return;
			
			wx.MessageDialog md = new wx.MessageDialog(this, Catalog.GetString("Do you really want to delete selected profile?"), 
				                                           Catalog.GetString("Delete profile"),
			                                           wx.MessageDialog.wxYES_NO|wx.MessageDialog.wxICON_QUESTION|wx.MessageDialog.wxNO_DEFAULT);
			if (md.ShowModal() == wx.MessageDialog.wxID_YES)
			{
				int selected = profilesList.Selection;
				ProfileData backup = profiles[selected];
				profiles.RemoveAt(selected);
				
				try
				{
					WriteProfileList(profiles);
				}
				catch (UnauthorizedAccessException e)
				{
					wx.MessageDialog error = new wx.MessageDialog(this, 
				                                           String.Format(
                                                               Catalog.GetString("Unable to write to profiles file:\n{0}\ncheck your permission\n\n{1}"), 
                                                               profilesFile, e.Message),
				                                           Catalog.GetString("Error"),
				                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
					error.ShowModal();
					
					profiles.Insert(selected, backup);					
					return;
				}
				
				// read profile list again
				FillControls();
				
				wx.MessageDialog md2 = new wx.MessageDialog(this, 
				                                            Catalog.GetString("Delete all profile data on disk (inculding contacts list and personal settings)?"), 
				                                           Catalog.GetString("Delete profile"),
			                                           wx.MessageDialog.wxYES_NO|wx.MessageDialog.wxICON_QUESTION|wx.MessageDialog.wxNO_DEFAULT);
				if (md2.ShowModal() == wx.MessageDialog.wxID_YES)
				{
					try
					{
						StringBuilder sb = new StringBuilder();
						sb.Append(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
						sb.Append(Path.DirectorySeparatorChar); 
						sb.Append(".");
						sb.Append(AppConfig.APP_NAME);
						sb.Append(Path.DirectorySeparatorChar); 
						sb.Append(backup.ProfileName);
						
						Directory.Delete(sb.ToString(), true);
					}
					catch (DirectoryNotFoundException e)
					{
						wx.MessageDialog error2 = new wx.MessageDialog(this, 
															String.Format(
																Catalog.GetString("Profile directory doesn't exist.\n\n {0}"), e.Message),
															Catalog.GetString("Error"),
															wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
						error2.ShowModal();     
					}
				}
			}
		}
		
		private void OnChangePasswordButtonClicked(object sender, wx.Event evt)
		{
			int selection = profilesList.Selection;
			if (selection >= 0)
			{
				ProfileData profile = profiles[selection];
				string oldPass, newPass;
				
				wx.TextEntryDialog passDlg = new wx.TextEntryDialog(this, Catalog.GetString("Please enter old profile password:"), 
				                                                    Catalog.GetString("Password"), string.Empty, 
				                                                    wx.TextCtrl.wxTE_PASSWORD|wx.TextEntryDialog.wxOK);
				if (passDlg.ShowModal() == wx.Window.wxID_OK)
				{
					oldPass = passDlg.Value;
				
					SaltedHash.SaltedHash hasher = new SaltedHash.SaltedHash();
					string oldHash = profile.PasswordHash;
					string oldSalt = profile.Salt;
					
					if (hasher.VerifyHashString(oldPass, oldHash, oldSalt))
					{
						passDlg = new wx.TextEntryDialog(this, Catalog.GetString("Please enter new profile password:"), 
				                                                    Catalog.GetString("Password"), string.Empty, 
				                                                    wx.TextCtrl.wxTE_PASSWORD|wx.TextEntryDialog.wxOK);
						if (passDlg.ShowModal() == wx.Window.wxID_OK)
						{
							newPass = passDlg.Value;
							if (newPass.Trim() == string.Empty)
							{
								wx.MessageDialog md = new wx.MessageDialog(this, 
						                                                                Catalog.GetString("Password cannot be empty"),
					                                           Catalog.GetString("Invalid password"),
				                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
								md.ShowModal(); 
								return;
							}
							
							string newHash, newSalt;
							hasher.GetHashAndSaltString(newPass, out newHash, out newSalt);
							profile.PasswordHash = newHash;
							profile.Salt = newSalt;
							
							try
							{
								WriteProfileList(profiles);
							}
							catch (Exception e)
							{
								wx.MessageDialog md = new wx.MessageDialog(this, String.Format(
								                                                               Catalog.GetString("Unable to write to profiles file:\n{0}\ncheck your permission\n\n{1}"), 
								                                                               profilesFile, e.Message),
							                                           Catalog.GetString("Error"),
						                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
								md.ShowModal();
								profiles.RemoveAt(profiles.Count-1);
								profileNameTC.Value = string.Empty;
								passwordTC.Value = string.Empty;
								
								return;
							}
						}
					}
					else
					{
						wx.MessageDialog md = new wx.MessageDialog(this, 
						                                                                Catalog.GetString(@"Entered password doesn't match with the selected profile."),
					                                           Catalog.GetString("Invalid password"),
				                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
						md.ShowModal();     
						return;
					}
				}
			}
		}
		
		private void OnUpButtonClicked(object sender, wx.Event evt)
		{
			int selection = profilesList.Selection;
			if (selection > 0)
			{
				ProfileData tmp = profiles[selection];
				profiles[selection] = profiles[selection - 1];
				profiles[selection - 1] = tmp;
				
				try
				{
					WriteProfileList(profiles);
				}
				catch (Exception e)
				{
					wx.MessageDialog md = new wx.MessageDialog(this, String.Format(
					                                                               Catalog.GetString("Unable to write to profiles file:\n{0}\ncheck your permission\n\n{1}"), 
					                                                               profilesFile, e.Message),
				                                           Catalog.GetString("Error"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
					md.ShowModal();
				}
				
				profilesList[selection - 1] = mainProfileNameCombo[selection - 1] = profiles[selection - 1].ProfileName;
				profilesList[selection] = mainProfileNameCombo[selection] = profiles[selection].ProfileName;
				profilesList.Selection = selection - 1;
				mainProfileNameCombo.Select(0);
			}
		}
		
		private void OnDownButtonClicked(object sender, wx.Event evt)
		{
			int selection = profilesList.Selection;
			if (selection >= 0 && selection <= profiles.Count)
			{
				ProfileData tmp = profiles[selection];
				profiles[selection] = profiles[selection + 1];
				profiles[selection + 1] = tmp;
				
				try
				{
					WriteProfileList(profiles);
				}
				catch (Exception e)
				{
					wx.MessageDialog md = new wx.MessageDialog(this, String.Format(
					                                                               Catalog.GetString("Unable to write to profiles file:\n{0}\ncheck your permission\n\n{1}"), 
					                                                               profilesFile, e.Message),
				                                           Catalog.GetString("Error"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
					md.ShowModal();
				}
				
				profilesList[selection + 1] = mainProfileNameCombo[selection + 1] = profiles[selection + 1].ProfileName;
				profilesList[selection] = mainProfileNameCombo[selection] = profiles[selection].ProfileName;
				profilesList.Selection = selection + 1;
				mainProfileNameCombo.Select(0);
				mainProfileNameCombo.Update();
			}
		}
		
		//// <value>
		/// Name of selected profile
		/// </value>
		public string ProfileName
		{
			get { return profileName; }
		}
		
		//// <value>
		/// Gadu-gadu password connected to profile UIN
		/// </value>
		public string Password
		{
			get { return password; }
		}
		
	}
}
